from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from web import models
import datetime, json
from django_redis import get_redis_connection
from utils.encrypt import uid
from utils.alipay import Alipay
from django.conf import settings


def index(request):
    return render(request, "index.html")


def price(request):
    """价格策略展示"""
    # 去数据库中查询所有收费版的价格策略，并返回给前端
    policy_list = models.PricePolicy.objects.filter(category=2)
    return render(request, "price.html", {"policy_list": policy_list})


def payment(request, policy_id):
    """支付页面"""
    # 1. 价格策略的id：policy_id
    # 根据policy_id去数据库中查找价格策略对象
    policy_object = models.PricePolicy.objects.filter(id=policy_id, category=2).first()
    if not policy_object:
        return redirect("web:price")
    # 2. 数量
    number = request.GET.get("number")
    if not number or not number.isdecimal():  # 为空或者不为数字
        return redirect("web:price")
    number = int(number)
    if number < 1:
        return redirect("web:price")

    # 3. 计算原价
    origin_price = number * policy_object.price
    # 4. 获取之前购买的套餐
    # 找到之前的订单，获取总的支付费用，并获取开始-结束的时间，计算剩余天数，再计算抵扣的钱
    balance = 0
    _object = None
    if request.tracer.price_policy.category == 2:  # 之前购买过
        _object = models.Transaction.objects.filter(user=request.tracer.user, price_policy__category=2).order_by(
            "-id").first()
        residue_time = _object.end_datetime - datetime.datetime.now()  # 剩余时间
        total_time = _object.end_datetime - _object.start_datetime
        if residue_time == total_time:  # 当天购买
            balance = _object.price * (residue_time.days - 1) / total_time.days
        else:
            balance = _object.price * residue_time.days / total_time.days

    if origin_price <= balance:  # 本次需要付的价格比抵扣的要少
        return redirect("web:price")

    context = {
        "policy_id": policy_id,
        "number": number,
        "origin_price": origin_price,
        "balance": round(balance, 2),
        "total_price": origin_price - round(balance, 2),
    }
    # 加订单信息添加到redis中，并设置超时时间为30分钟
    conn = get_redis_connection()
    key = "payment{}".format(request.tracer.user.mobile_phone)
    conn.set(key, json.dumps(context), ex=60 * 30)
    context["policy_object"] = policy_object
    context["transaction"] = _object

    print(context)
    return render(request, "payment.html", context)


"""
def pay(request):
    # 生成订单 & 去支付宝支付
    conn = get_redis_connection()
    key = "payment{}".format(request.tracer.user.mobile_phone)
    context_string = conn.get(key)
    if not context_string:
        return redirect("web:price")

    context = json.loads(context_string.decode("utf-8"))
    print(context)
    # 1. 去数据库中去生成订单,未支付状态
    order_id = uid(request.tracer.user.mobile_phone)
    total_price = context["total_price"]
    models.Transaction.objects.create(
        status=2,
        user=request.tracer.user,
        price_policy_id=context["policy_id"],
        price=context["total_price"],
        count=context["number"],
        order=order_id,
    )

    # 2. 跳转到支付宝页面去支付
    # - 生成一个支付宝的链接
    # - 跳转到这个链接
    # 构造字典
    params = {
        'app_id': "2021000117611674",
        'method': "alipay.trade.page.pay",
        'format': "JSON",
        'return_url': "http://127.0.0.1:8001/pay/notify/ ",
        'notify_url': "http://127.0.0.1:8001/pay/notify/",
        'charset': "utf-8",
        'sign_type': 'RSA2',
        'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        'version': "1.0",
        'biz_content': json.dumps({
            'out_trade_no': order_id,
            'product_code': "FAST_INSTANT_TRADE_PAY",
            'total_amount': total_price,
            'subject': "tracer payment",
        }, separators=(",", ":"))

    }
    # 获取签名的字符串
    unsigned_string = "&".join(["{0}={1}".format(k, params[k]) for k in sorted(params)])


    # 签名SH256WITHRSA
    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.Hash import SHA256
    from base64 import decodebytes, encodebytes

    private_key = RSA.importKey(open(r"D:\路飞学城\s28\s28\files\应用私钥2048.txt").read())
    signer = PKCS1_v1_5.new(private_key)
    signature = signer.sign(SHA256.new(unsigned_string.encode('utf-8')))

    # base64编码，转换为字符串
    sign_string = encodebytes(signature).decode("utf-8").replace("\n", "")

    # 把生成的签名赋值给sign参数，拼接到请求参数中
    from urllib.parse import quote_plus
    result = "&".join(["{0}={1}".format(k, quote_plus(params[k])) for k in sorted(params)])
    result = result + "&sign=" + quote_plus(sign_string)
    print(result)
    gate_way = "https://openapi.alipaydev.com/gateway.do"
    pay_url = "{}?{}".format(gate_way, result)
    return redirect(pay_url)
"""


# 封装版
def pay(request):
    """ 生成订单 & 去支付宝支付"""
    conn = get_redis_connection()
    key = "payment{}".format(request.tracer.user.mobile_phone)
    context_string = conn.get(key)
    if not context_string:
        return redirect("web:price")

    context = json.loads(context_string.decode("utf-8"))
    print(context)
    # 1. 去数据库中去生成订单,未支付状态
    order_id = uid(request.tracer.user.mobile_phone)
    total_price = context["total_price"]
    models.Transaction.objects.create(
        status=2,
        user=request.tracer.user,
        price_policy_id=context["policy_id"],
        price=context["total_price"],
        count=context["number"],
        order=order_id,
    )

    alipay = Alipay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRIVATE_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    query_params = alipay.direct_pay(
        subject="Tracer payment",  # 商品简单描述
        out_trade_no=order_id,  # 商户订单
        total_amount=total_price  # 交易金额
    )
    print(query_params)
    pay_url = "{}?{}".format(settings.ALI_GATEWAY, query_params)
    return redirect(pay_url)


def pay_notify(request):
    """支付成功之后触发的url"""
    print(request.method)
    alipay = Alipay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRIVATE_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    if request.method == "GET":
        # 只做跳转，判断是否支付成功了，不做订单的状态更新
        # 支付宝会将订单号返回，还有签名认证：获取订单ID,然后根据订单ID做状态更新
        # 通过支付宝的公钥对支付宝返回的数据，request.GET 进行检查，通过了才表示是支付宝返回的接口

        params = request.GET.dict()
        sign = params.pop("sign")
        status = alipay.verify(params, sign)
        print("GET验证", status)
        if status:
            return HttpResponse("支付成功")
        return HttpResponse("支付失败")
    else:
        # 做订单状态的更新
        from urllib.parse import parse_qs
        body_str = request.body.decode("utf-8")
        post_data = parse_qs(body_str)
        post_dict = {}
        for k, v in post_data.items():
            post_dict[k] = v[0]
        sign = post_dict.pop("sign")
        status = alipay.verify(post_dict, sign)
        if status:
            out_trade_no = post_dict["out_trade_no"]
            _object = models.Transaction.objects.filter(order=out_trade_no).first()
            _object.status = 1
            current_datetime = datetime.datetime.now()
            _object.start_datetime = current_datetime
            _object.end_datetime = _object.start_datetime + datetime.timedelta(days=_object.count*365)
            _object.save()
            return HttpResponse("success")
        return HttpResponse("error")


